package cn.fotoit.product.config;

import cn.fotoit.product.system.entity.Permission;
import cn.fotoit.product.system.entity.Role;
import cn.fotoit.product.system.entity.RoleRelPermission;
import cn.fotoit.product.system.entity.User;
import cn.fotoit.product.system.repository.PermissionRepository;
import cn.fotoit.product.system.repository.RoleRelPermissionRepository;
import cn.fotoit.product.system.repository.RoleRepository;
import cn.fotoit.product.system.repository.UserRepository;
import lombok.extern.slf4j.Slf4j;
import org.apache.shiro.authc.*;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.authz.SimpleAuthorizationInfo;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.subject.PrincipalCollection;
import org.apache.shiro.util.ByteSource;
import org.springframework.beans.factory.annotation.Autowired;

import java.util.ArrayList;
import java.util.List;
import java.util.Optional;

@Slf4j
public class ShiroRealm extends AuthorizingRealm {

    @Autowired
    private UserRepository userRepository;
    @Autowired
    private PermissionRepository permissionRepository;
    @Autowired
    private RoleRepository roleRepository;
    @Autowired
    private RoleRelPermissionRepository roleRelPermissionRepository;

    @Override
    public AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {

        UsernamePasswordToken upToken = (UsernamePasswordToken) token;
        String username = upToken.getUsername();
        Optional<User> byLoginName = userRepository.findByLoginName(username);
        log.info("对" + username + "进行数据库用户密码验证");
        if (!byLoginName.isPresent()) {
            throw new UnknownAccountException("用户名密码错误!");
        }
        User user = byLoginName.get();
        if (user.getIsLock()) {
            throw new LockedAccountException("用户被锁定");
        }
        Object credentials = user.getLoginPassword();
        //加盐,默认使用用户名
        ByteSource salt = ByteSource.Util.bytes(username);
        String realmName = getName();
        SimpleAuthenticationInfo info = new SimpleAuthenticationInfo(user.getId(), credentials, salt, realmName);
        return info;
    }

    @Override
    public AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
        Integer userId = (Integer) principalCollection.getPrimaryPrincipal();
        Optional<User> byId = userRepository.findById(userId);
        SimpleAuthorizationInfo info = new SimpleAuthorizationInfo();
        if (byId.isPresent()) {
            User user = byId.get();
            log.info("对" + user.getNickName() + "进行数据库权限验证");
            Optional<Role> roleRepositoryById = roleRepository.findById(user.getRoleId());
            if (roleRepositoryById.isPresent()) {
                Role role = roleRepositoryById.get();
                List<RoleRelPermission> byRoleId = roleRelPermissionRepository.findByRoleId(role.getId());
                List<Integer> ids = new ArrayList<>();
                for (RoleRelPermission roleRelPermission : byRoleId) {
                    ids.add(roleRelPermission.getPermissionId());
                }
                List<Permission> byIdIn = permissionRepository.findByIdIn(ids);
                for (Permission permission : byIdIn) {
                    info.addStringPermission(permission.getPermissionKey());
                }
                info.addRole(role.getRoleKey());
            }
        }
        return info;
    }


}
